home *** CD-ROM | disk | FTP | other *** search
/ Symantec Visual Cafe for Java 2.5 / symantec-visual-cafe-2.5-database-dev-edition.iso / Visual Cafe Pro v1.0 / SOURCE.BIN / WrappingLabel.java < prev    next >
Encoding:
Java Source  |  1997-06-19  |  8.2 KB  |  339 lines

  1. package symantec.itools.awt;
  2.  
  3.  
  4. import java.awt.Canvas;
  5. import java.awt.Graphics;
  6. import java.awt.FontMetrics;
  7. import java.awt.Dimension;
  8. import java.awt.Label;
  9.  
  10.  
  11. /**
  12.  * Wrapping label.  Displays text on one or more lines, wrapping text
  13.  * as needed to fit in the available horizontal space.
  14.  *
  15.  * @version 1.0, Nov 26, 1996
  16.  *
  17.  * @author    Symantec
  18.  */
  19.  
  20. public class WrappingLabel
  21.     extends    Canvas
  22.     implements AlignStyle
  23. {
  24.     //--------------------------------------------------
  25.     // constants
  26.     //--------------------------------------------------
  27.  
  28.  
  29.     //--------------------------------------------------
  30.     // class variables
  31.     //--------------------------------------------------
  32.  
  33.  
  34.     //--------------------------------------------------
  35.     // member variables
  36.     //--------------------------------------------------
  37.  
  38.     /**
  39.      * The text string being displayed.
  40.      */
  41.     protected String text;
  42.  
  43.     /**
  44.      * Current text alignment.
  45.      * @see symantec.itools.awt.AlignStyle
  46.      */
  47.     protected int align;
  48.  
  49.     /**
  50.      * Maximum ascent of the font used to display text.
  51.      *
  52.      */
  53.     protected int baseline;
  54.  
  55.     /**
  56.      * Metrics of the font used to display text.
  57.      */
  58.     protected FontMetrics fm;
  59.  
  60.  
  61.     //--------------------------------------------------
  62.     // constructors
  63.     //--------------------------------------------------
  64.  
  65.     /**
  66.      * Create default wrapping label. Default values are an empty text string
  67.      * and left alignment.
  68.      */
  69.     public WrappingLabel()
  70.     {
  71.         this("");
  72.     }
  73.  
  74.     /**
  75.      * Create a wrapping label that displays the specified string.
  76.      * The label will default to left alignment.
  77.      *
  78.      * @param s string to be displayed in label
  79.      */
  80.  
  81.     public WrappingLabel(String s)
  82.     {
  83.         this(s, WrappingLabel.ALIGN_LEFT);
  84.     }
  85.     /**
  86.      * Create wrapping label with specified text and alignment.
  87.      *
  88.      * @param s string to be displayed in label
  89.      * @param a alignment, one of ALIGN_LEFT, ALIGN_CENTERED, or ALIGN_RIGHT
  90.      *
  91.      * @see symantec.itools.awt.AlignStyle
  92.      */
  93.  
  94.     public WrappingLabel(String s, int a)
  95.     {
  96.         setText(s);
  97.         setAlignStyle(a);
  98.     }
  99.  
  100.  
  101.     //--------------------------------------------------
  102.     // accessor members
  103.     //--------------------------------------------------
  104.  
  105.     /**
  106.      * Gets the current text alignment setting.
  107.      *
  108.      * @return the current alignment, one of ALIGN_LEFT, ALIGN_CENTERED, or ALIGN_RIGHT
  109.      * @see #setAlignStyle
  110.      * @see symantec.itools.awt.AlignStyle
  111.      */
  112.     public int getAlignStyle()
  113.     {
  114.         return align;
  115.     }
  116.  
  117.     /**
  118.      * Sets current text alignment.
  119.      *
  120.      * @param an alignment style, one of ALIGN_LEFT, ALIGN_CENTERED, or ALIGN_RIGHT
  121.      * @see #getAlignStyle
  122.      * @see symantec.itools.awt.AlignStyle
  123.      */
  124.  
  125.     public void setAlignStyle(int a)
  126.     {
  127.         align = a;
  128.         invalidate();
  129.     }
  130.  
  131.     /**
  132.      * Gets the current label text.
  133.      *
  134.      * @return the label's text string
  135.      * @see #setText
  136.      */
  137.     public String getText()
  138.     {
  139.         return text;
  140.     }
  141.  
  142.     /**
  143.      * Sets the label text.
  144.      *
  145.      * @param s the new label text
  146.      *
  147.      * @see #getText
  148.      */
  149.     public void setText(String s)
  150.     {
  151.         text = s;
  152.         repaint();
  153.     }
  154.  
  155.     //--------------------------------------------------
  156.     // event methods
  157.     //--------------------------------------------------
  158.  
  159.  
  160.     //--------------------------------------------------
  161.     // class methods
  162.     //--------------------------------------------------
  163.  
  164.  
  165.     //--------------------------------------------------
  166.     // member methods
  167.     //--------------------------------------------------
  168.  
  169.     /**
  170.      * Returns an empty string.
  171.      * This is a standard Java AWT method which typically returns a string
  172.      * representing the state of this object.
  173.      *
  174.      * @return the empty string
  175.      */
  176.     public String paramString()
  177.     {
  178.         return "";
  179.     }
  180.  
  181.     /**
  182.      * Paints this component using the given graphics context.
  183.      * This is a standard Java AWT method which typically gets called
  184.      * by the AWT to handle painting this component. It paints this component
  185.      * using the given graphics context. The graphics context clipping region
  186.      * is set to the bounding rectangle of this component and its <0,0>
  187.      * coordinate is this component's top-left corner.
  188.      *
  189.      * @param g the graphics context used for painting
  190.      * @see java.awt.Component#repaint
  191.      * @see java.awt.Component#update
  192.      */
  193.     public void paint(Graphics g)
  194.     {
  195.         if (text != null)
  196.         {
  197.             int x, y;
  198.             int boundx, boundy;
  199.             Dimension d;
  200.             int fromIndex = 0;
  201.             int pos = 0;
  202.             int bestpos;
  203.             String largestString;
  204.             String s;
  205.  
  206.             // Set up some class variables
  207.             fm = getToolkit().getFontMetrics(getFont());
  208.             baseline = fm.getMaxAscent();
  209.  
  210.             // Get the maximum height and width of the current control
  211.             d = size();
  212.             boundx = d.width;
  213.             boundy = d.height;
  214.  
  215.             // X and Y represent the coordinates of the upper left portion
  216.             // of the next text line.
  217.             x = 0;
  218.             y = 0;
  219.  
  220.             // While we haven't passed the bottom of the label and we
  221.             // haven't run past the end of the string...
  222.             while ((y + fm.getHeight()) <= boundy && fromIndex != -1)
  223.             {
  224.                 // Automatically skip any spaces at the beginning of the line
  225.                 while (fromIndex < text.length() && text.charAt(fromIndex) == ' ')
  226.                 {
  227.                     ++fromIndex;
  228.                     // If we hit the end of line while skipping spaces, we're done.
  229.                     if (fromIndex >= text.length()) break;
  230.                 }
  231.  
  232.                 // fromIndex represents the beginning of the line
  233.                 pos = fromIndex;
  234.                 bestpos = -1;
  235.                 largestString = null;
  236.  
  237.                 while (pos >= fromIndex)
  238.                 {
  239.                     pos = text.indexOf(' ', pos);
  240.  
  241.                     // Couldn't find another space?
  242.                     if (pos == -1)
  243.                     {
  244.                         s = text.substring(fromIndex);
  245.                     }
  246.                     else
  247.                     {
  248.                         s = text.substring(fromIndex, pos);
  249.                     }
  250.  
  251.                     // If the string fits, keep track of it.
  252.                     if (fm.stringWidth(s) < boundx)
  253.                     {
  254.                         largestString = s;
  255.                         bestpos = pos;
  256.  
  257.                         // If we've hit the end of the string, use it.
  258.                         if (pos == -1) break;
  259.                     }
  260.                     else
  261.                     {
  262.                         break;
  263.                     }
  264.  
  265.                     ++pos;
  266.                 }
  267.  
  268.                 if (largestString == null)
  269.                 {
  270.                     // Couldn't wrap at a space, so find the largest line
  271.                     // that fits and print that.  Note that this will be
  272.                     // slightly off -- the width of a string will not necessarily
  273.                     // be the sum of the width of its characters, due to kerning.
  274.                     int totalWidth = 0;
  275.                     int oneCharWidth = 0;
  276.  
  277.                     pos = fromIndex;
  278.  
  279.                     while (pos < text.length())
  280.                     {
  281.                         oneCharWidth = fm.charWidth(text.charAt(pos));
  282.                         if ((totalWidth + oneCharWidth) >= boundx) break;
  283.                         totalWidth += oneCharWidth;
  284.                         ++pos;
  285.                     }
  286.  
  287.                     drawAlignedString(g, text.substring(fromIndex, pos), x, y, boundx);
  288.                     fromIndex = pos;
  289.                 }
  290.                 else
  291.                 {
  292.                     drawAlignedString(g, largestString, x, y, boundx);
  293.  
  294.                     fromIndex = bestpos;
  295.                 }
  296.  
  297.                 y += fm.getHeight();
  298.             }
  299.  
  300.             // We're done with the font metrics...
  301.             fm = null;
  302.         }
  303.     }
  304.  
  305.     /**
  306.      * This helper method draws a string aligned the requested way.
  307.      * @param g the graphics context used for painting
  308.      * @param s the string to draw
  309.      * @param x the point to start drawing from, x coordinate
  310.      * @param y the point to start drawing from, y coordinate
  311.      * @param width the width of the area to draw in, in pixels
  312.      */
  313.     protected void drawAlignedString(Graphics g, String s, int x, int y, int width)
  314.     {
  315.         int drawx;
  316.         int drawy;
  317.  
  318.         drawx = x;
  319.         drawy = y + baseline;
  320.  
  321.         if (align != WrappingLabel.ALIGN_LEFT)
  322.         {
  323.             int sw;
  324.  
  325.             sw = fm.stringWidth(s);
  326.  
  327.             if (align == WrappingLabel.ALIGN_CENTERED)
  328.             {
  329.                 drawx += (width - sw) / 2;
  330.             }
  331.             else if (align == WrappingLabel.ALIGN_RIGHT)
  332.             {
  333.                 drawx = drawx + width - sw;
  334.             }
  335.         }
  336.  
  337.         g.drawString(s, drawx, drawy);
  338.     }
  339. }